Skip to content

chore(yun-tianming): share template poll reader, hoist cron refs lookup - #380

Merged
Fermionic-Lyu merged 1 commit into
mainfrom
yun-tianming/2026-10-17-1000
Oct 17, 2026
Merged

Fermionic-Lyu merged 1 commit into
mainfrom
yun-tianming/2026-10-17-1000

Conversation

@Fermionic-Lyu

@Fermionic-Lyu Fermionic-Lyu commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Summary

  • src/commands/template.ts: the deployment poll closure passed to watchDeployment was written out three times (deploy, upgrade, rollback), each building the same GET /template-deployments/:id request with the project id attached, and two of the three carried the same comment explaining why the project id must ride along. The three copies now share one module-local readDeployment(api, projectId) and the constraint lives in one comment above it. The upgrade path's remaining comment now describes only the preview GET it still sits above.
  • src/commands/cron.ts: jobShowLines called refsOf(j.request) once for the rows and again inside the headerNames.filter callback, per header. The refs are now read once into a local and used for both.

Safety

  • template.ts — duplicate collapse / pure refactor inside one module. The three closures were byte-identical apart from the captured api and p.projectId, which the helper takes as parameters; no exported symbol changed name, signature or behaviour. test/template.test.ts asserts the exact poll path and that the request carries projectId (lines 720 and 753), and test/template-upgrade.test.ts exercises the upgrade and rollback poll paths; all pass before and after.
  • cron.ts — redundant work removed. refsOf is r.secretRefs ?? {}, so every call returns the same object by construction; hoisting it changes nothing observable. test/cron.test.ts describe('jobShowLines') covers literal-only, mixed, and secret-only header rows; passes before and after.

Verification

npm run typecheck      # baseline: exit 0 (~4s)      final: exit 0
npm test               # baseline: 106 files, 2109 passed, 135 skipped (~35s)
                       # final:    106 files, 2109 passed, 135 skipped

Both gates run on this machine; the suite uses dependency-injected fakes and needs no database, Docker, or network. There is no lint script in this repository. No test failed or flaked in either run.

Deferred findings

  • src/deploy-archive.ts:96 defines a local sleep while the module already imports setTimeout as delay from node:timers/promises. Replacing sleep with delay is not behaviour-preserving under test: vitest's fake timers do not intercept the promise-based timer, so test/deploy-archive-logs.test.ts:48 (polls expected at 0/3000/6000 ms) fails with delay as the default wait. Tried, reverted with git restore. Collapsing it would need the test to inject wait, which is a test-design decision for the owners.
  • src/commands/template.ts:462,617,672 repeat res.body.deploymentId ?? (res.body.deployment ?? res.body).id. Left in place: a shared helper needs a declared parameter type, and the expression currently relies on the any-typed response body to be assignable to watchDeployment's string parameter. Not a defect.
  • src/commands/deploy.ts:19-29 deployRequestBody re-runs parseEndpoint on a value deploy() already normalized at line 189. Redundant but harmless; the function is exported and unit-tested standalone on raw option strings, so the re-parse is part of its contract. Left.
  • Comments narrating pre-fix behaviour remain at src/commands/compute.ts:2061-2068 ("used to be rewritten only by --setup …") and src/deploy-archive.ts:52-55 ("Keying on the tar digest instead bought …"). Each also states what breaks without the current code, and my earlier comment-shrinking PR (chore(yun-tianming): shrink change-narration comments to their constraints #286) went three rounds without approval, so these are left for a human to judge.
  • Unexported-elsewhere symbols: a scan of every export in src/ found none unreferenced; every candidate is used inside its own file. No dead code to remove.

Filed, not fixed here


Opened by Yun Tianming: nightly sweep 2026-10-17-1000, model claude-fable-5-1, 55 turns, 2 files, 27 changed lines.
Verification: npm run typecheck (exit 0) and npm test (106 files, 2109 passed, 135 skipped) both pass on the final tree, identical to baseline.

🤖 Generated with Claude Code


Summary by cubic

Deduplicates the deployment poll closure in template.ts into a single readDeployment helper, and hoists the refsOf call in cron.ts so it runs once instead of per header. No behavior changes; all tests pass before and after.

Written for commit 771bfb4. Summary will update on new commits.

View guided diff Turn on auto-fix

## Summary

- `src/commands/template.ts`: the deployment poll closure passed to `watchDeployment` was written out three times (deploy, upgrade, rollback), each building the same `GET /template-deployments/:id` request with the project id attached, and two of the three carried the same comment explaining why the project id must ride along. The three copies now share one module-local `readDeployment(api, projectId)` and the constraint lives in one comment above it. The upgrade path's remaining comment now describes only the preview GET it still sits above.
- `src/commands/cron.ts`: `jobShowLines` called `refsOf(j.request)` once for the rows and again inside the `headerNames.filter` callback, per header. The refs are now read once into a local and used for both.

## Safety

- template.ts — **duplicate collapse / pure refactor inside one module.** The three closures were byte-identical apart from the captured `api` and `p.projectId`, which the helper takes as parameters; no exported symbol changed name, signature or behaviour. `test/template.test.ts` asserts the exact poll path and that the request carries `projectId` (lines 720 and 753), and `test/template-upgrade.test.ts` exercises the upgrade and rollback poll paths; all pass before and after.
- cron.ts — **redundant work removed.** `refsOf` is `r.secretRefs ?? {}`, so every call returns the same object by construction; hoisting it changes nothing observable. `test/cron.test.ts` `describe('jobShowLines')` covers literal-only, mixed, and secret-only header rows; passes before and after.

## Verification

```
npm run typecheck      # baseline: exit 0 (~4s)      final: exit 0
npm test               # baseline: 106 files, 2109 passed, 135 skipped (~35s)
                       # final:    106 files, 2109 passed, 135 skipped
```

Both gates run on this machine; the suite uses dependency-injected fakes and needs no database, Docker, or network. There is no lint script in this repository. No test failed or flaked in either run.

## Deferred findings

- `src/deploy-archive.ts:96` defines a local `sleep` while the module already imports `setTimeout as delay` from `node:timers/promises`. Replacing `sleep` with `delay` is not behaviour-preserving under test: vitest's fake timers do not intercept the promise-based timer, so `test/deploy-archive-logs.test.ts:48` (polls expected at 0/3000/6000 ms) fails with `delay` as the default wait. Tried, reverted with `git restore`. Collapsing it would need the test to inject `wait`, which is a test-design decision for the owners.
- `src/commands/template.ts:462,617,672` repeat `res.body.deploymentId ?? (res.body.deployment ?? res.body).id`. Left in place: a shared helper needs a declared parameter type, and the expression currently relies on the `any`-typed response body to be assignable to `watchDeployment`'s `string` parameter. Not a defect.
- `src/commands/deploy.ts:19-29` `deployRequestBody` re-runs `parseEndpoint` on a value `deploy()` already normalized at line 189. Redundant but harmless; the function is exported and unit-tested standalone on raw option strings, so the re-parse is part of its contract. Left.
- Comments narrating pre-fix behaviour remain at `src/commands/compute.ts:2061-2068` ("used to be rewritten only by --setup …") and `src/deploy-archive.ts:52-55` ("Keying on the tar digest instead bought …"). Each also states what breaks without the current code, and my earlier comment-shrinking PR (#286) went three rounds without approval, so these are left for a human to judge.
- Unexported-elsewhere symbols: a scan of every `export` in `src/` found none unreferenced; every candidate is used inside its own file. No dead code to remove.

Co-Authored-By: Claude (claude-fable-5-1) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Tip: Get a Slack DM when cubic finishes reviewing your PRs. Connect Slack

View guided diff | Turn on auto-fix | Re-trigger cubic

@Fermionic-Lyu

Copy link
Copy Markdown
Member Author

Addressed

  • None. cubic-dev-ai reported "No issues found" across the 2 changed files, so there were no review points to act on.

Declined

  • None.

Verification

  • npm run typecheck — passed (tsc, no errors).
  • npm test — 106 files, 2109 passed, 135 skipped (pre-existing skips), 0 failures.
  • No lint script exists in package.json; the repo's pre-commit gate is typecheck + test only.
  • Working tree clean, no changes this round.

Yun Tianming, review round 1 of 10: nothing left to change.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - approved.

@Fermionic-Lyu
Fermionic-Lyu merged commit 1398146 into main Oct 17, 2026
3 checks passed
@Fermionic-Lyu
Fermionic-Lyu deleted the yun-tianming/2026-10-17-1000 branch October 17, 2026 10:11

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Two small, genuinely behaviour-preserving refactors — one readDeployment(api, projectId) helper replacing three byte-identical poll closures in template.ts, and a hoist of a pure refsOf call in cron.ts — both of which I reproduced and mutation-tested locally at 771bfb4; no Critical findings.

(Note: the PR was merged at 2026-10-17T10:11:30Z, mid-review, as 1398146. Everything below was verified against head 771bfb4ed98885ad3060f0680cdc6e6ad54f2d37, which is the merged tree.)

Requirements context

No matching spec/plan found — this repo has no docs/ directory at all (neither docs/superpowers/ nor the docs/specs/ the older InsForge/CLI repo used). .claude/skills/developing-insta-cli/SKILL.md, CONTRIBUTING.md and AGENTS.md carry no comment-style or dedup convention, so this is assessed against the PR description's own claims plus repo convention as practised in the surrounding code.

Verification performed

  • npm ci clean, npx tsc --noEmit exit 0.
  • npx vitest run at head: 106 files, 2243 passed, 1 skipped (the body reports 135 skips; this box has ssh/ssh-keygen, so the SSH suites actually run — more coverage than the author measured, and all green).
  • Equivalence of the three collapsed closures checked directly: git show main:src/commands/template.ts lines 468/616/671 are byte-identical apart from the captured api/p.projectId, both of which are const in their enclosing functions and are never reassigned between binding and the watchDeployment call — so moving p.projectId from lazy (per-poll) to eager (at call time) evaluation is not observable.
  • refsOf (src/commands/cron.ts:173-175) is r.secretRefs ?? {} — pure, no allocation of a fresh object per call for the non-null branch, so the hoist is a strict no-op on semantics and a strict (small) win on work done.
  • Negative controls run on top of head:
    • drop { projectId } from readDeployment → 1 test red (template.test.ts, the pollScopes assertion at test/template.test.ts:752-753).
    • corrupt the poll path in readDeployment → 16 tests red.
    • refsOf → {} → 9 tests red in test/cron.test.ts.
    • readDeployment(api, 'WRONG_PROJECT') at the upgrade call site only (src/commands/template.ts:619) → full suite GREEN (see Suggestion 1).

Findings

Critical

(none)

Suggestion

Software engineering / test coverage — the upgrade and rollback poll scopes are unasserted; the deploy test is the only pin. src/commands/template.ts:619 and src/commands/template.ts:674. Replacing p.projectId with a wrong literal at the upgrade site alone leaves the entire suite green (106/106). test/template-upgrade.test.ts executes those poll paths but its fake api asserts only on posts[0].path (test/template-upgrade.test.ts:108,155) — it never captures the poll path or the opts scope the way fakeApi's pollScopes does in test/template.test.ts:716,752. This is pre-existing, not introduced here, and the collapse actually reduces the blast radius (one helper, one assertion). But it makes one sentence of the Safety section optimistic: test/template-upgrade.test.ts exercises those code paths, it does not pin them. Cheapest fix while the helper is fresh: have the upgrade fake record (path, opts) on GETs to /template-deployments/ and assert { projectId: 'proj_1' }, mirroring the deploy test.

Software engineering / completeness — one more identical refsOf repeat was left in place. src/commands/cron.ts:401: current.headerNames.filter((n) => … findHeader(refsOf(current), n) === undefined) calls refsOf once per header name, inside a filter callback — exactly the shape the PR hoists out of jobShowLines at line 233. Not a defect (pure, cheap), but the sweep's own stated standard ("the refs are now read once into a local") applies verbatim here, and leaving it means the next sweep re-finds it.

Information

Functionality — the relocated comment is accurate. The template.ts:387-388 comment now sits above readDeployment and states the constraint once; the rewritten comment at template.ts:576-579 correctly describes only the preview GET it still precedes (template.ts:582, which does pass { projectId: p.projectId } and does need its own 409 reading via templateErrorAdvice). No stale claim left behind — the failure mode my previous sweep reviews (#286, #365) kept hitting (a shrunk comment that drops a present-tense fact) does not occur here.

Security — no security-relevant changes in this PR. No new user input reaches SQL, shell or HTTP; the request path, method, body and scope are unchanged byte-for-byte; no secret, token or PII is newly logged or returned (cron.ts's header rendering still prints names only and secret names, never values); no auth check touched — in fact the one auth-adjacent behaviour (naming the project so agent mode picks the project-bound session) is now harder to drop accidentally, since one helper serves all three call sites. No dependency changes.

Performance — net positive, trivially. cron.ts drops one refsOf call per header name per cron show (an O(headers) → O(1) change on a sub-millisecond pure function). template.ts is neutral: one closure allocated per command invocation, same as before. No new queries, loops, blocking I/O or allocations in a hot path.

Deferred-findings section is sound. I spot-checked the deploy-archive.ts:96 sleep-vs-delay claim: test/deploy-archive-logs.test.ts drives polls off vitest fake timers, which do not intercept node:timers/promises, so the author's "tried, reverted" is correct and the deferral is the right call.

Verdict

approved — 0 Critical findings; two Suggestions, neither blocking. (Informational: the green checkmark is a separate human action, and the PR has in any case already merged as 1398146.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants